package com.ac.scum.log.task.utils.map;

import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component
@AllArgsConstructor
public class GameMapZoneUtil {
    private final static char[] xChars = {'0', '1', '2', '3', '4'};
    private final static char[] yChars = {'Z', 'A', 'B', 'C', 'D'};
    private final static double blockSize = 304800;
    private final static double offset = 904800;
    private final static int minZoneIndex = 0;
    private final static int maxZoneIndex = 4;

    private static final Map<String, Region> regions = Maps.newHashMap();
    private static final Map<String, Set<String>> gridZones = Maps.newHashMap();

    static {
        //D4
        addRegion("空军基地", 522991.49650318, 626670.06657643, 427865.51570831, 533844.63542167);
        addRegion("地堡", 411278.94043096, 571068.97695574, 393063.32651031, 558993.60401741);
        addRegion("二战碉堡", 418338.11089830, 608004.36673567, 407527.21808360, 598947.83703192);
        addRegion("二战碉堡", 568653.94934922, 500066.78146749, 553252.12944883, 485878.21826495);
        addRegion("海边小镇", 593237.62342100, 359854.45270006, 552659.75176036, 330873.55764807);
        addRegion("大城", 387386.37667540, 431224.15373054, 245215.73144102, 315300.57352259);
        //D3
        addRegion("小镇", 286583.44604561, 527648.76259140, 246301.76322920, 490215.10648258);
        addRegion("地堡", 157543.83354649, 569945.20707863, 124370.68299180, 539153.00608589);
        //D2
        addRegion("村子", -15134.26264443, 547970.27683247, -39717.93671621, 527442.14283731);
        addRegion("地堡", -229574.98587294, 589152.16139996, -257712.92607558, 565907.06849368);
        addRegion("伐木场", -74964.40918056, 515172.62441855, -111099.44817763, 486493.61369002);
        addRegion("城堡", -102954.25496108, 361724.62422072, -132869.32822915, 336064.45672677);
        //D1
        addRegion("小镇", -306880.27421914, 586260.19414653, -335018.21442177, 561807.56394641);
        addRegion("加油站", -400920.23226479, 571155.03880062, -408473.04779287, 566324.88962529);
        addRegion("鬼屋", -473091.58215068, 624705.31924315, -487901.02436259, 613007.30170914);
        addRegion("地堡", -522209.56398037, 559245.23526105, -551828.44840419, 534792.60506094);
        addRegion("矿洞", -437647.64895034, 443411.27533651, -471709.36603774, 418958.64513640);
        //D0
        addRegion("瀑布", -673413.96896401, 605358.90954835, -684372.95620083, 596604.26416807);
        addRegion("地堡", -858334.53135746, 618984.58535618, -886324.37713798, 594833.83947953);
        addRegion("军营", -842389.70460195, 560457.39826232, -877636.17706630, 509137.06327442);
        //C4
        addRegion("二战碉堡", 542095.67695655, 278802.30650912, 534098.57816211, 273217.44652515);
        addRegion("地堡", 456546.47180503, 279570.64440184, 433443.74195445, 255872.72501037);
        addRegion("医院", 383387.82727818, 313541.69467708, 360729.38069395, 291051.31257944);
        addRegion("小镇", 574182.79572305, 245658.40640973, 555226.70969180, 227545.34700224);
        addRegion("二战碉堡", 588794.79075743, 128558.40945602, 582722.91945054, 125388.62405971);
        //C3
        addRegion("二战碉堡", 233318.03871142, 284321.54066793, 227098.07298242, 281151.75527162);
        addRegion("地堡", 200488.12537624, 308783.86906262, 175608.26246023, 291878.34694896);
        addRegion("加油站", 195628.01280158, 155246.42459408, 186594.25305232, 149208.73812492);
        addRegion("帐篷", 239366.00176731, 98288.03628988, 231961.28066136, 92250.34982072);
        addRegion("小镇", 181041.48486905, 53323.21203239, 147868.33431436, 23738.54833349);
        //C2
        addRegion("大坝", 8067.19079493, 278252.79155386, -25698.33744824, 238102.17653391);
        addRegion("交易区", -130549.18830859, 312077.95833534, -163722.33886328, 283700.83193027);
        addRegion("地堡", -202769.89546938, 205430.72631515, -229130.70260659, 183695.05502615);
        addRegion("监狱", -48307.41319912, 167681.62130836, -83850.07450771, 144285.58624035);
        addRegion("二战碉堡", -226242.86137526, 95263.97350704, -234684.24343605, 90584.76649344);
        addRegion("二战碉堡", -28018.47736879, 66348.79804457, -37496.52038442, 60990.35130318);
        addRegion("小镇", -175372.42737734, 86126.31560726, -196327.78810720, 66126.47917815);
        //C1
        addRegion("天文台", -311224.37425498, 221830.54806868, -341929.28142802, 181039.66803158);
        addRegion("地堡", -379446.54105751, 233373.02898830, -407584.48126015, 212844.89499314);
        addRegion("小镇", -465933.68357509, 211640.35815818, -514804.84287441, 174810.47069628);
        //C0
        addRegion("核电站", -662504.33448261, 250197.05706134, -739513.43398456, 178952.35672520);
        addRegion("辐射大城", -742870.25293789, 187407.11808795, -892741.80812246, 36464.95635884);
        addRegion("地堡", -882079.00972988, 246548.18655827, -901035.09576113, 217969.48985429);
        //B4
        addRegion("地堡", 460051.36710254, 1321.34189861, 428951.53845752, -25244.47856571);
        addRegion("大岛", 601530.91105967, -76486.80622918, 539627.44261387, -132939.17471587);
        addRegion("小岛", 600642.34452696, -252520.99725449, 544366.46412168, -290256.53768677);
        addRegion("交易区", 589979.54613438, -206936.46441230, 558287.33980088, -237124.89675813);
        addRegion("海边小镇", 510008.55819004, -162556.71844331, 460248.83235801, -201801.68049288);
        //B3
        addRegion("新兵训练营", 265948.95053770, -20628.07984070, 232923.89440513, -45382.59436427);
        addRegion("地堡", 253410.27741299, -81107.70103612, 222902.82645645, -117937.58849803);
        addRegion("火车站", 109067.60475811, -151064.62022901, 77967.77611309, -183668.12716250);
        addRegion("小镇", 303268.74491172, -160964.48317505, 267429.89475889, -198549.08144560);
        addRegion("采石场", 149472.68754100, -275002.85600998, 115633.11208677, -296663.05621810);
        //B2
        addRegion("小镇", -38236.99701450, -70781.07003021, -70225.39219223, -99611.02292047);
        addRegion("靶场", -210544.85263063, -104590.89647271, -328600.79247627, -125206.93634478);
        addRegion("机场", -221380.42182304, -14269.63116097, -287726.72293242, -61061.70129699);
        addRegion("地堡", -31572.74349965, -187938.25517010, -55564.03988295, -204541.89296030);
        //B1
        addRegion("工厂", 389220.77291738, 10179.56101335, -424763.43422597, -21197.34321052);
        addRegion("小镇", -446089.03101113, -92786.80942824, -477485.04850039, -122975.24177407);
        addRegion("地堡", -565749.32408339, -246507.18943723, -595072.01966298, -282733.30825222);
        //B0
        addRegion("养老院", -601291.98539199, -113631.70502213, -656679.29926455, -193329.16641510);
        addRegion("地堡", -792629.97876992, -76503.93384861, -815732.70862050, -95220.76190302);
        addRegion("废车场", -849498.23686367, -162855.10223141, -883856.14279531, -212666.01560201);
        addRegion("砖厂", -761826.33896914, -277175.88996506, -795739.96163442, -296194.60234293);
        //A4
        addRegion("小镇", 350066.58230137, -361276.86555379, 321632.45325450, -393880.37248728);
        addRegion("地堡", 460150.10876924, -391867.81340182, 436455.00123018, -419339.28683652);
        addRegion("灯塔", 569838.70472618, -396900.71595130, 530149.39959825, -430107.99153171);
        addRegion("海军基地", 535776.98763877, -510468.98071091, 439515.61326133, -588355.13616313);
        addRegion("小机场", 386201.62129844, -514997.24556278, 335849.51777793, -543978.14061477);
        //A3
        addRegion("采石场", 155816.06227544, -299439.39460479, 116867.22925811, -377929.31870393);
        addRegion("地堡", 242944.94427588, -444516.25510873, 215399.38176172, -462931.19883968);
        addRegion("海边小镇", 212289.39889722, -508175.65862367, 175710.07663379, -528854.73478056);
        //A2
        addRegion("地堡", -28907.04390151, -322636.10971806, -56452.60641567, -338485.03669962);
        addRegion("小镇", -19429.00088588, -477858.97278319, -77333.91993447, -515594.51321546);
        addRegion("灯塔", -214173.16597255, -480880.69145753, -256083.88743227, -514691.73568485);
        //A1
        addRegion("鱼工厂", 328576.10705959, -353295.55883102, -355159.05582998, -384842.47063240);
        addRegion("地堡", -333833.45904482, -458513.99735348, -359898.07733779, -480249.66864247);
        //A0
        addRegion("地堡", -759851.74968720, -346603.60290008, -776808.56101984, -367056.26581437);
        addRegion("交易区", 597811.76647219, -550050.14483235, -629109.05585319, -587584.43211991);
        //Z4
        addRegion("灯塔", 608121.11284397, -675314.73936784, 590942.15987815, -697352.29498029);
        addRegion("地堡", 528002.03047752, -826922.77299168, 512526.16336607, -847224.49374425);
        addRegion("海岛小镇", 462322.15426768, -813550.73333981, 392569.68144957, -867437.08507710);
        //Z3
        addRegion("赛车场", 289644.05807676, -747716.00966445, 248325.71430552, -821526.72674999);
        addRegion("海盗灯塔", 309710.85227391, -882945.34976602, 301269.47021312, -890718.87109507);
        addRegion("海边小镇", 227043.29814736, -668043.11913493, 126740.19374571, -750404.08915888);
        addRegion("造船厂", 161246.19409947, -762962.79555085, 140142.73894749, -779113.60685586);
        addRegion("地堡", 40993.52333873, -812791.20929504, 23962.66479502, -829696.73140870);
        //Z2
        addRegion("灯塔", -64893.98847646, -878484.08594964, -72002.52073818, -884446.30133794);
        addRegion("地堡", -192724.15792221, -645894.26525099, -208792.40272214, -664233.73790107);
        addRegion("小镇", -131980.76169643, -667372.52316204, -180555.73215151, -715975.89923881);
        addRegion("火车站", -252085.33803505, -723554.63716260, -293403.68180629, -784384.32833943);
        //Z1
        addRegion("火车站", -295921.28698232, -730029.64774609, -375892.27492666, -790406.51243773);
        addRegion("高达工厂", -412965.24225082, -664622.94347340, -457936.58478066, -721572.76105830);
        //地堡 -554148.59284423 -721892.14805854  -576807.03942846 -746495.72042039
        addRegion("地堡", -554148.59284423, -721892.14805854, -576807.03942846, -746495.72042039);

        //Z0
        addRegion("小机场", -744943.57484755, -653183.27235434, -764788.22741152, -699069.12693395);
        addRegion("地堡", -680670.59564785, -795581.30247553, -709845.19680532, -810373.63432498);
    }


    private static String getStringZone(double x, double y) {
        double gameX = x + offset;
        double gameY = y + offset;
        int blockX = (int) ((gameX) / blockSize);
        int blockY = (int) ((gameY) / blockSize);

        blockX = Math.min(Math.max(blockX, minZoneIndex), maxZoneIndex);
        blockY = Math.min(Math.max(blockY, minZoneIndex), maxZoneIndex);

        return "" + yChars[blockY] + xChars[blockX];
    }

    public String getZone(double x, double y) {
        return getStringZone(x, y) + "-" + findRegion(x, y);
    }

    private static void addRegionToGrid(String gridKey, String regionKey) {
        gridZones.computeIfAbsent(gridKey, k -> new HashSet<>()).add(regionKey);
    }

    public static void addRegion(String name, double topLeftX, double topLeftY, double bottomRightX, double bottomRightY) {
        String regionKey = "region:" + name;
        Region region = new Region(name, topLeftX, topLeftY, bottomRightX, bottomRightY);
        regions.put(regionKey, region);

        String gridKey1 = getStringZone(topLeftX, topLeftY);
        String gridKey2 = getStringZone(bottomRightX, bottomRightY);
        addRegionToGrid(gridKey1, regionKey);
        if (!gridKey1.equals(gridKey2)) {
            addRegionToGrid(gridKey2, regionKey);
        }
    }

    public String findRegion(double x, double y) {
        Set<String> regionKeys = getRegionsInGrid(x, y);
        for (String regionKey : regionKeys) {
            Region region = regions.get(regionKey);
            if (region != null && x <= region.getTopLeftX() && x >= region.getBottomRightX() && y <= region.getTopLeftY() && y >= region.getBottomRightY()) {
                return region.getName();
            }
        }
        return "野外";
    }

    private static Set<String> getRegionsInGrid(double x, double y) {
        String gridKey = getStringZone(x, y);
        return gridZones.getOrDefault(gridKey, Collections.emptySet());
    }

}
